import libtcodpy as libtcod
import ent

class Limb(object):
	def __init__(self, name="none", dmg_multiply = 1):
		self.name = name
		self.damaged = False
		self.dmg_multiply = dmg_multiply
		self.owner = None
		
	def take_damage(self, damage):
		if not self.damaged:
			self.damaged = True
			actor = self.owner
			actor.em.services["render"].message(actor.name + "'s " + self.name + " is damaged", libtcod.magenta)

#simple body simulation. Bleeding, limb loss, etcetra
class Damage(object):
	def __init__(self, dmg, type = "generic", inflictor = None):
		self.dmg = dmg
		self.type = type
		self.inflictor = inflictor
	
	
class BodySimulation():
	def __init__(self):
		self.bleeding = False
		self.stunned = False
		self.stun_duration = 0;
		
		self.blood_level = 100	#100% blood
		
		self.bleed_inflictor = None
		
		self.owner = None
		
		self.limbs = [
			Limb("head",3),
			Limb("left arm"),
			Limb("right arm"),
			Limb("left leg"),
			Limb("right leg"),
			Limb("chest",2),
			Limb("left eye",0.2),
			Limb("right eye",0.2)
		]
		
		
		self.stamina = 100
		self.hunger = 100
	#-------------------------------------------------------------------	
	def set_hunger(self, amt):
		self.hunger = amt
		
		if self.hunger < 0:
			self.hunger = 0
			
		if self.hunger > 100:
			self.hunger = 100
					
	#-------------------------------------------------------------------		
	def set_stamina(self, amt):
		self.stamina = amt
		
		if self.stamina < 0:
			self.stamina = 0
			
		if self.stamina > self.owner.combat.get_max_stamina():
			self.stamina = self.owner.combat.get_max_stamina()
	#-------------------------------------------------------------------
	def set_hp(self, amt):
		self.owner.hp = self.owner.hp + amt
		max_hp = self.owner.combat.get_max_hp()
		if self.owner.hp > max_hp:
			self.owner.hp = max_hp
	
	def heal(self, amt):
		self.set_hp(self.owner.hp + amt)
	
	def get_limb(self,limb_id):
		pass
		
	def set_owner(self,owner):
		self.owner = owner
		for limb in self.limbs:
			limb.owner = owner
		
	def take_damage(self,damage):
		#print "body simulation: take_damage()"
		
		render = self.owner.em.services["render"]
		if isinstance(damage,Damage):
			if damage.type == "dmg_cut":
				if not self.bleeding:
					render.message(self.owner.name + " is bleeding",libtcod.red)
				self.bleeding = True
				self.bleed_inflictor = damage.inflictor
				
			elif damage.type == "dmg_blunt":
				
				print "inflictor is: "+ damage.inflictor.name
				
				if hasattr( damage.inflictor, "combat" ):
					chance = damage.inflictor.combat.get_stun_chance()
				else:
					chance = 5

				seed = libtcod.random_get_int(0,0,100)
				if  seed <= chance:	
					if not self.stunned:
						render.message(self.owner.name + " is stunned",libtcod.red)
					self.stunned = True
					self.stun_duration = self.owner.combat.get_stun_duration()
				else:
					print "stun chance : %d, seed: %d "	% (chance, seed)
				
				
			else:
				#print "damage type is" + damage.type
				pass
		
			#damage resistance by armor value
			#===========================================================
			if self.owner.combat:
				defence = self.owner.combat.get_defence()
				#todo: move to combat
				if defence > 100:
					defence = 100
				damage.dmg = damage.dmg - ( damage.dmg * defence / 100 )
			#===========================================================
			limb = self.limbs[libtcod.random_get_int(0, 0, len(self.limbs))-1]
			limb.take_damage(damage)
		
	def can_move(self):
		if self.stunned:
			return False
		#todo: check limb condition
		
		return True
				
	def think(self):
		objects = self.owner.em.services["objects"]
		map = self.owner.em.services["map"]
		
		map_objects = map.get_objects(self.owner.x, self.owner.y)
		
		if self.bleeding:
			self.blood_level -= 5
			
			if self.blood_level <= 0 and self.owner.is_alive():
				self.owner.take_damage(Damage(10,"dmg_bloodloss", self.bleed_inflictor))
				
				
			map.get_tile(self.owner.x,self.owner.y).blood = True
			
		if self.stunned:
			#self.owner.model = "?"
			
			self.stun_duration = self.stun_duration-1
			if self.stun_duration <= 0:
				self.stunned = False
			
			
		#update hunger and stamina values
		self.set_hunger(self.hunger-0.05)
		self.set_stamina(self.stamina-0.1)
	
